﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace DNA.Mvc.jQuery
{
    public class GridColumn<TModel, TValue> : GridColumn
    {
        //public new void RenderCell(HtmlTextWriter writer, TModel data)
        //{
        //    var value = DataBinder.Eval(data, DataField);
        //    if (!this.CellTemplate.IsEmpty)
        //        this.CellTemplate.WriteTo(data,writer);
        //    else
        //    {
        //        if (!string.IsNullOrEmpty(FormatString))
        //            writer.Write(FormatString, value);
        //        else
        //            writer.Write(value);
        //    }
        //}


        public ModelMetadata Metadata { get; protected set; }

        public GridColumn() { }

        public GridColumn(ModelMetadata meta)
        {
            Title = string.IsNullOrEmpty(meta.DisplayName) ? meta.PropertyName : meta.DisplayName;
            DataField = meta.PropertyName;
            if (!string.IsNullOrEmpty(meta.DisplayFormatString))
                FormatString = meta.DisplayFormatString;
            if (meta.ContainerType != null)
            {
                var prop = meta.ContainerType.GetProperty(meta.PropertyName);
                DataType = prop.PropertyType.ToString();
            }

            if (!string.IsNullOrEmpty(meta.Description))
                this.MergeAttribute("title", meta.Description);
            this.Metadata = meta;
        }

        //private HtmlTemplate<TModel> cellTemplate = new HtmlTemplate<TModel>();

        //public new HtmlTemplate<TModel> CellTemplate
        //{
        //    get { return cellTemplate; }
        //    set { cellTemplate = value; }
        //}
    }

    public class GridColumn : ViewComponent
    {
        private Grid grid;
        private HorizontalAlign textAlign = HorizontalAlign.Left;

        public HorizontalAlign TextAlign
        {
            get { return textAlign; }
            set { textAlign = value; }
        }
        public Grid Grid
        {
            get { return grid; }
            internal set { grid = value; }
        }

        public override string TagName
        {
            get
            {
                return "th";
            }
        }

        private SortingOrders sortingOrder = SortingOrders.NotSet;

        public SortingOrders SortingOrder
        {
            get { return sortingOrder; }
            set { sortingOrder = value; }
        }

        public override void RenderBeginTag(HtmlTextWriter writer)
        {
            var @class = "d-grid-column" + (IsResizable ? " d-grid-column-resizable" : "");
            //var @class = "";
            if (SortingOrder != SortingOrders.NotSet)
            {
                if (SortingOrder == SortingOrders.Asc)
                    @class += " d-grid-column-asc";
                else
                    @class += " d-grid-column-desc";
            }
            // if (!string.IsNullOrEmpty(@class))
            MergeAttribute("scope", "col");
            MergeAttribute("class", @class);
            base.RenderBeginTag(writer);
        }

        public override void RenderContent(HtmlTextWriter writer)
        {
            var column = new TagBuilder("a");
            column.MergeAttribute("href", "javascript:void(0);");
            var hidden = new TagBuilder("input");
            hidden.MergeAttribute("type", "hidden");
            hidden.MergeAttribute("value", DataField);
            if (SortingOrder != SortingOrders.NotSet)
                column.InnerHtml = Title + "<span class=\"d-grid-column-sorting-icon\"></span>";
            else
                column.InnerHtml = Title;
            writer.Write(column.ToString());
            writer.Write(hidden.ToString(TagRenderMode.SelfClosing));
        }

        private HtmlTemplate<object> cellTemplate = new HtmlTemplate<object>();

        public virtual HtmlTemplate<object> CellTemplate
        {
            get { return cellTemplate; }
            set { cellTemplate = value; }
        }

        private  HtmlTemplate clientCellTemplate = new HtmlTemplate();

        public virtual HtmlTemplate ClientCellTemplate
        {
            get { return clientCellTemplate; }
            set { clientCellTemplate = value; }
        }

        public string Title { get; set; }

        public string DataField { get; set; }

        public string DataType { get; set; }

        public string FormatString { get; set; }

        public virtual void RenderCell(HtmlTextWriter writer, object data)
        {
            var value = DataBinder.Eval(data, DataField);
            if (!CellTemplate.IsEmpty)
                CellTemplate.WriteTo(data,writer);
            else
            {
                if (!string.IsNullOrEmpty(FormatString))
                    writer.Write(FormatString, value);
                else
                    writer.Write(value);
            }
        }

        private bool resizable = false;

        public bool IsResizable
        {
            get { return resizable; }
            set { resizable = value; }
        }

        internal string FilterOperator { get; set; }

        internal string FilterTerm { get; set; }

        public void RenderFilter(HtmlTextWriter writer)
        {
            var helper = new AjaxHelper(ViewContext, ViewDataContainer);
            Type type = Type.GetType(DataType);
            writer.WriteFullBeginTag("td");
            var combo = helper.Dna().ComboBox(Name + "_filterExpr")
                .DropDownStyle(DropdownStyles.DropdownList)
                .Options(opts =>
                {
                    var scripts = new StringBuilder()
                                            .Append("if (ui.value) { if ($(\"#")
                                            .Append(Name)
                                            .Append("_filterValue\").val()) $(\"#")
                                            .Append(Grid.Id)
                                            .Append("\").dgrid(\"addFilter\",\"")
                                            .Append(DataField).Append("\",ui.value,");
                    var strVal = "$(\"#" + Name + "_filterValue\").val()";

                    if (type.Equals(typeof(String)))
                    {
                        scripts.AppendFormat(" ((ui.value==\"eq\") || (ui.value==\"neq\")) ? \"'\"+{0}+\"'\" : {0} ", strVal);
                    }
                    else
                    {
                        scripts.Append(strVal);
                    }

                    scripts.Append(",true);  } else { $(\"#")
                    .Append(Grid.Id)
                    .Append("\").dgrid(\"removeFilter\",\"")
                    .Append(DataField)
                    .Append("\"); }");
                    opts.OnItemSelected = scripts.ToString();
                    opts.AutoFitWith = true;
                })
                .Items(items =>
                {
                    items.AddValue("Clear filter", "");
                    items.AddValue("Is equal", "eq");
                    items.AddValue("Is not equal", "neq");

                    if (type.Equals(typeof(String)))
                    {
                        items.AddValue("Starts with", "startswith");
                        items.AddValue("Contains", "contains");
                        items.AddValue("Not Contains", "not~contains");
                        items.AddValue("Ends with", "endswith");
                    }

                    if ((type.Equals(typeof(Int16))) || (type.Equals(typeof(Int32)))
                        || (type.Equals(typeof(Int64)))
                        || (type.Equals(typeof(float)))
                        || (type.Equals(typeof(decimal)))
                        || (type.Equals(typeof(double))))
                    {
                        items.AddValue("Is less than", "lt");
                        items.AddValue("Is less than or equal", "le");
                        items.AddValue("Is greater than", "gt");
                        items.AddValue("Is greater than or equal", "ge");
                    }
                });

            if (Width > 0)
                combo.Width(Width - 5);
            if (!string.IsNullOrEmpty(FilterOperator))
                combo.Select(FilterOperator);

            writer.WriteFullBeginTag("div");
            combo.Render();
            writer.WriteEndTag("div");
            writer.WriteFullBeginTag("div");
            if (type.Equals(typeof(bool)))
            {
                helper.Dna().ComboBox(Name + "_filterValue")
                   .Items(items =>
                   {
                       items.AddValue("Checked", "true");
                       items.AddValue("Unchecked", "false");
                   }).Options(opts => { opts.AutoFitWith = true; })
                   .Render();

                //if (Width > 0)
                //boolCombo.Width(Width);

                //boolCombo.Render();
            }
            else
            {
                var textbox = helper.Dna().TextBox(Name + "_filterValue");
                if (!string.IsNullOrEmpty(FilterTerm))
                    textbox.Value(FilterTerm.Replace("'", "").Replace("%", ""));

                if (Width > 0)
                    textbox.Width(Width - 5);
                textbox.Render();
            }

            writer.WriteEndTag("div");
            writer.WriteEndTag("td");
        }
    }

}
